import { PLASMIC } from "@/plasmic-init";
import {
  ComponentRenderData,
  extractPlasmicQueryData,
  PlasmicComponent,
  PlasmicRootProvider,
} from "@plasmicapp/loader-nextjs";
import type { GetStaticPaths, GetStaticProps } from "next";
import { notFound } from "next/navigation";
import { useRouter } from "next/router";

export default function PlasmicLoaderPage(props: {
  plasmicData?: ComponentRenderData;
  queryCache?: Record<string, any>;
}) {
  const { plasmicData, queryCache } = props;
  const router = useRouter();
  if (!plasmicData || plasmicData.entryCompMetas.length === 0) {
    notFound();
  }
  const pageMeta = plasmicData.entryCompMetas[0];
  return (
    <PlasmicRootProvider
      loader={PLASMIC}
      prefetchedData={plasmicData}
      prefetchedQueryData={queryCache}
      pageParams={pageMeta.params}
      pageQuery={router.query}
    >
      <PlasmicComponent
        component={pageMeta.displayName}
        componentProps={
          pageMeta.path === "/"
            ? {
                staticHref: "/pages/static",
                dynamicHref: "/pages/dynamic/foo",
                codeHref: "/pages/code",
                children: (
                  <>
                    <span>
                      This page is from the pages/ directory (works for all
                      Next.js versions).
                    </span>
                    <span>
                      {
                        // Can't use next/link for client-side navigation between pages/ and app/.
                        // https://github.com/vercel/next.js/issues/42513#issuecomment-1315006245
                      }
                      {/* eslint-disable-next-line @next/next/no-html-link-for-pages */}
                      <a href="/app">Click here</a> to view pages from the app/
                      directory (new Next.js 13 feature).
                    </span>
                  </>
                ),
              }
            : undefined
        }
      />
    </PlasmicRootProvider>
  );
}

export const getStaticProps: GetStaticProps = async (context) => {
  const { catchall } = context.params ?? {};
  const plasmicPath =
    typeof catchall === "string"
      ? catchall
      : Array.isArray(catchall)
      ? `/${catchall.join("/")}`
      : "/";
  const plasmicData = await PLASMIC.maybeFetchComponentData(plasmicPath);
  if (!plasmicData) {
    notFound();
  }
  const pageMeta = plasmicData.entryCompMetas[0];
  // Cache the necessary data fetched for the page
  const queryCache = await extractPlasmicQueryData(
    <PlasmicRootProvider
      loader={PLASMIC}
      prefetchedData={plasmicData}
      pageParams={pageMeta.params}
    >
      <PlasmicComponent component={pageMeta.displayName} />
    </PlasmicRootProvider>
  );
  // Use revalidate if you want incremental static regeneration
  return { props: { plasmicData, queryCache }, revalidate: 60 };
};

export const getStaticPaths: GetStaticPaths = async () => {
  const pageModules = await PLASMIC.fetchPages();
  return {
    paths: pageModules.map((mod) => ({
      params: {
        catchall: mod.path.substring(1).split("/"),
      },
    })),
    fallback: "blocking",
  };
};
